package com.mall.common.interceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.mall.common.bean.User;
import com.mall.common.domain.OperateLogDomain;
import com.mall.common.log.Log;
import com.mall.common.log.Logs;
import com.mall.common.service.OperateLogService;
import com.mall.common.util.SpringUtils;

public class LogInterceptor implements HandlerInterceptor {
	@Resource private OperateLogService operateLogService;

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		HandlerMethod hm = (HandlerMethod) handler;
		Logs logs = hm.getMethodAnnotation(Logs.class);
		if(logs != null){
			for(Log log : logs.logs()){
				log(log, request);
			}
		}else{
			log(hm.getMethodAnnotation(Log.class), request);
		}
	}

	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

	}
	
	private String getOperator(){
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		if (authentication == null) {
			return null;
		}
		Object principal = authentication.getPrincipal();
		if (principal == null || !(principal instanceof User)) {
			return null;
		} else {
			return ((User) principal).getUsername();
		}
	}
	
	private void log(Log log, HttpServletRequest request){
		if(log == null){
			return;
		}
		String message = null;
		if(StringUtils.isNotBlank(log.message())){
			message = log.message();
		}else if(StringUtils.isNotBlank(log.code())){
			Object[] args = null;
			if(log.args() != null && log.args().length > 0){
				args = log.args();
			}else if(log.params() != null && log.params().length > 0){
				args = new Object[log.params().length];
				for(int i = 0;i < log.params().length;i++){
					String[] values = request.getParameterValues(log.params()[i]);
					if(values != null && values.length > 0){
						args[i] = values.length > 1?StringUtils.join(values, ","):values[0];
					}
				}
			}
			message = SpringUtils.getMessage(log.code(), args);
		}
		operateLogService.persist(new OperateLogDomain(message, log.type(), getOperator()));
	}

}
